extends Node3D

# 模仿b站搬运 BV15f4y17ER 的做法
# 然而GD4.0好像没有ClippedCamera了（已经改用springarm实现，不过效果不好就弃用了……那玩意开放世界用比较好）
# 由于这里直接记录了相机朝向的信息，就不像player里面那种看起来头大的欧拉方向引用了，而是直接在这里操作，并传递信号了
signal rotate_cube(direction:Vector3i)

var camrot_h:float = 0
var camrot_v:float = 0
var cam_v_max:float = PI/2
var cam_v_min:float = -PI/2
var h_sensitivity:float = 0.005
var v_sensitivity:float = 0.005
var h_acceleration:float = 15
var v_acceleration:float = 15
var joypad_sensitivity:float = 2

# Called when the node enters the scene tree for the first time.
func _ready():
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	#get_window().focus_entered.connect(window_catch_mouse) #直接让主窗口自带一个信号了
#func window_catch_mouse():
	#Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	#现在有手动切换了就不用这个自动切换了



	



func _input(event:InputEvent):
	if event is InputEventMouseMotion: # 鼠标手感要比触摸快，“硬”一些
		if Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
			camrot_h += -event.relative.x  * h_sensitivity
			camrot_v += -event.relative.y  * v_sensitivity
			camrot_v = clamp(camrot_v, cam_v_min, cam_v_max)
			# 鼠标：立刻执行
			$h.rotation.y = camrot_h
			$h/v.rotation.x = camrot_v 
	#两个手指同时拖动会出问题……另外弄个节点来处理了
	#elif event is InputEventScreenDrag: # 触摸的手感要柔和一点，不宜太硬
		#camrot_h += -event.relative.x  * h_sensitivity
		#camrot_v += -event.relative.y  * v_sensitivity  
		#camrot_v = clamp(camrot_v, cam_v_min, cam_v_max)
	# 视角改变，但是不是鼠标
	

func handle_single_drag(event:InputEventScreenDrag):
	camrot_h += -event.relative.x  * h_sensitivity
	camrot_v += -event.relative.y  * v_sensitivity  
	camrot_v = clamp(camrot_v, cam_v_min, cam_v_max)
	



func _physics_process(delta):
	
	var sight_change := Vector2.ZERO
	sight_change.x = Input.get_axis(&"look_left", &"look_right")
	sight_change.y = Input.get_axis(&"look_up", &"look_down")
	sight_change = sight_change.normalized() * clamp(sight_change.length(),0,1)
	# Move The player Towards Spring Arm/sight Rotation
	camrot_h -= sight_change.x * joypad_sensitivity * delta
	camrot_v -= sight_change.y * joypad_sensitivity * delta
	#camrot_h = wrapf(camrot_h, 0, 2 * PI)
	camrot_v = clamp(camrot_v, cam_v_min, cam_v_max)
	$h.rotation.y = lerp($h.rotation.y, camrot_h, delta * h_acceleration)
	$h/v.rotation.x = lerp($h/v.rotation.x, camrot_v, delta * v_acceleration)
	#$h.rotation.y = camrot_h
	#$h/v.rotation.x = camrot_v # 镜头朝下为负，水平为0，朝上为正（弧度制）

func _process(delta):
	if Input.is_action_just_pressed(&"switch_mouse_release"): # O键
		match Input.mouse_mode:
			Input.MOUSE_MODE_VISIBLE:
				Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
			_:
				Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
	# 由于模拟触摸，左键现在也不能拿来控制了
	if Input.is_action_just_pressed(&"B_rotate"): #左键或者I  注意B面在前方（远处）而F面才是近处
		rotate_cube.emit(normalized_B()) #位置只有player节点知道
	if Input.is_action_just_pressed(&"F_rotate"): #右键或者K
		rotate_cube.emit(-normalized_B())
	
	if Input.is_action_just_pressed(&"L_rotate"): # J键
		rotate_cube.emit(normalized_L())
	if Input.is_action_just_pressed(&"R_rotate"): # L键
		rotate_cube.emit(-normalized_L())
	
	if Input.is_action_just_pressed(&"U_rotate"): # U键
		rotate_cube.emit(normalized_U()) 
	if Input.is_action_just_pressed(&"D_rotate"): # O键
		rotate_cube.emit(-normalized_U())
	
	

func normalized_B() -> Vector3i:
	if camrot_v > PI/4:
		return Vector3i(0,1,0)
	elif camrot_v < -PI/4:
		return Vector3i(0,-1,0)
	else:
		# 一开始面向橙色z-，在绿色x+时值为负，转到红色z+正好负PI
		# 所以，-pi/4到pi/4为z-，pi/4到3pi/4为x-……
		match posmod(round((camrot_h)/ (PI/2)),4):
			0:
				return Vector3i(0,0,-1)
			1:
				return Vector3i(-1,0,0)
			2:
				return Vector3i(0,0,1)
			_:
				return Vector3i(1,0,0)

func normalized_L() -> Vector3i:
	# 不用管俯仰角了，因为轮盘式这种视角控制方式的特殊性
	match posmod(round((camrot_h)/ (PI/2)),4):
		0:
			return Vector3i(-1,0,0)
		1:
			return Vector3i(0,0,1)
		2:
			return Vector3i(1,0,0)
		_:
			return Vector3i(0,0,-1)

func normalized_U() -> Vector3i:
	if camrot_v > PI/4:
		#视角向上，有点反向……“上”实际上是“后”
		match posmod(round((camrot_h)/ (PI/2)),4):
			0:
				return -Vector3i(0,0,-1)
			1:
				return -Vector3i(-1,0,0)
			2:
				return -Vector3i(0,0,1)
			_:
				return -Vector3i(1,0,0)
	elif camrot_v < -PI/4:
		#视角向下，那么“上”就是实际的前（B面）
		match posmod(round((camrot_h)/ (PI/2)),4):
			0:
				return Vector3i(0,0,-1)
			1:
				return Vector3i(-1,0,0)
			2:
				return Vector3i(0,0,1)
			_:
				return Vector3i(1,0,0)
	else: # 俯仰角在中间，不上也不下，“上”就是上了
		return Vector3i(0,1,0)
